package com.pubinfo.passbook.data.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.mychain.gov.sdk.base.HttpClientUtils;
import com.pubinfo.passbook.common.config.ApplicationConfig;
import com.pubinfo.passbook.common.entity.TBankApplyReceipt;
import com.pubinfo.passbook.common.entity.TBankId;
import com.pubinfo.passbook.common.exception.ServiceException;
import com.pubinfo.passbook.common.mapper.TBankApplyReceiptMapper;
import com.pubinfo.passbook.common.model.bo.bank.*;
import com.pubinfo.passbook.common.model.dto.financial.InvoiceResult;
import com.pubinfo.passbook.common.service.master.TBankApplyReceiptService;
import com.pubinfo.passbook.common.service.master.TBankIdService;
import com.pubinfo.passbook.common.utils.tax.Util;
import com.pubinfo.passbook.data.service.BankService;
import com.pubinfo.passbook.data.service.TFileInfoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class BankServiceImpl implements BankService
{
    @Resource
    ApplicationConfig config;
    @Autowired
    TBankApplyReceiptService tBankApplyReceiptService;
    @Autowired
    TBankIdService tBankIdService;
    @Autowired
    TBankApplyReceiptMapper tBankApplyReceiptMapper;
    @Autowired
    TFileInfoService tFileInfoService;

    @Override
    public Boolean batchApplyReceipt(String startDate, String endDate) throws IOException, ParseException {
        List<String> dateList = Util.getTaxTwoDaysDay(startDate, endDate);
        List<TBankId> tBankIds=tBankIdService.list();
        for(String s:dateList)
        {
            for(TBankId bankId:tBankIds)
            {
                //比申请通过时间早就跳过
                if(new SimpleDateFormat("yyyy-MM-dd").parse(s).before(bankId.getStartDate()))
                {
                    continue;
                }
                BankResult<String> bankResult=applyReceipt(new BankApplyReceipt(s,"0","0",bankId.getBankId(),bankId.getPlatformId()));
                if(!"0000".equals(bankResult.getCode()))
                {
                    throw new ServiceException("银行回单获取错误:" + bankResult.getMessage());
                }
            }
        }
        return true;
    }

    @Override
    public BankResult<String> applyReceipt(BankApplyReceipt bankApplyReceipt) throws IOException {

        BankBillBase billBase = new BankBillBase(config.getBank(), BankBillBase.Method.apply_receipt, JSONObject.toJSONString(bankApplyReceipt));

        String postString = postBillBase(billBase,0);

        BankResult<String> bankResult = JSONObject.parseObject(postString, BankResult.class);
        if (StringUtils.isEmpty(bankResult) || bankResult.getCode() == null) {
              throw new ServiceException("申请银行单失败:数据:" + JSON.toJSONString(bankResult));
        }

        TBankApplyReceipt tBankApplyReceipt=new TBankApplyReceipt(bankResult.getData(),bankApplyReceipt,JSONObject.toJSONString(billBase));

        tBankApplyReceiptService.save(tBankApplyReceipt);

        return bankResult;
    }

    @Override
    public TBankApplyReceipt queryReceipt(String bankId) throws IOException
    {
        TBankApplyReceipt tBankApplyReceipt=tBankApplyReceiptService.getById(bankId);

        BankQueryReceipt bankQueryReceipt=new BankQueryReceipt(tBankApplyReceipt);

        BankBillBase billBase = new BankBillBase(config.getBank(), BankBillBase.Method.query_receipt, JSONObject.toJSONString(bankQueryReceipt));

        String postString = postBillBase(billBase,0);

        BankResult<BankQueryReceiptDate> bankResult = JSONObject.parseObject(postString, BankResult.class);

        if (StringUtils.isEmpty(bankResult) || bankResult.getCode() == null) {
            throw new ServiceException("查询银行单据失败:数据:" + JSON.toJSONString(bankResult));
        }
        BankQueryReceiptDate bankQueryReceiptDate=JSONObject.parseObject(JSON.toJSONString(bankResult.getData()),BankQueryReceiptDate.class);

        tBankApplyReceipt.setStatus(bankQueryReceiptDate.getStatus());
        tBankApplyReceipt.setFileUrl(bankQueryReceiptDate.getFileUrl());

        tBankApplyReceiptService.updateById(tBankApplyReceipt);

        return tBankApplyReceipt;
    }

    @Override
    @Transactional
    public Boolean syncBankApplyReceipt() throws IOException {
        List<TBankId> tBankIds=tBankIdService.list();

        for(TBankId tBankId:tBankIds)
        {
            BankApplyReceipt bankApplyReceipt=new BankApplyReceipt(tBankId,"0","0");
            //同步银行回单
            applyReceipt(bankApplyReceipt);
        }
        return true;
    }

    @Override
    public Boolean syncBankReconciliationStatement() throws IOException {
        List<TBankId> tBankIds=tBankIdService.list();

        for(TBankId tBankId:tBankIds)
        {
            BankApplyReceipt bankApplyReceipt=new BankApplyReceipt(tBankId,"1","1");
            //银行月对账单
            applyReceipt(bankApplyReceipt);
        }

        return true;
    }

    @Override
    @Transactional
    public Boolean syncBankQueryReceipt() throws Exception {
        List<TBankApplyReceipt> tBankApplyReceipts=tBankApplyReceiptMapper.selectNeedSynApplyReceipt();
        for(TBankApplyReceipt tBankApplyReceipt:tBankApplyReceipts)
        {
            TBankApplyReceipt bankApplyReceipt=queryReceipt(tBankApplyReceipt.getId());
            if(bankApplyReceipt.getStatus()==3)
            {
                tFileInfoService.saveBankFile(bankApplyReceipt);
            }
        }
        return true;
    }

    private String postBillBase(BankBillBase billBase,int count){
        String url = config.getBank().getUrl();
        String params = JSONObject.toJSONString(billBase);
        try
        {
            return HttpClientUtils.doPost(url,params, ContentType.APPLICATION_JSON);
        }
        catch (Exception e)
        {
            if(count<=2)
            {
                return postBillBase(billBase,count++);
            }
        }
        throw new ServiceException("请求"+url+"错误");
    }
}
